import axios, { AxiosError, AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import { config } from './config'
import { useUserStoreHook } from '@/store/modules/user'
import { isCheckTimeout } from '@/utils/auth'

const { result_code, request_timeout } = config

const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASEPATH,
  timeout: request_timeout
})

service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  if (config && config.headers) {
    const useStore = useUserStoreHook()
    if (useStore.getToken) {
      if (isCheckTimeout()) {
        // token超时，自动退出登录
        useStore.logout()
        return Promise.reject(new Error('token 失效,请重新登录'))
      }
      // 如果 token 存在，注入token
      config.headers['Authorization'] = useStore.getToken
    }
  }
  return config
}, (error: AxiosError) => {
  return Promise.reject(error)
})

service.interceptors.response.use((response: AxiosResponse<any>) => {
  if (response.data.toString() === '[object Blob]') {
    const blob = new Blob([response.data])
    if (response.data.type === 'application/json') {
      const reader = new FileReader()
      reader.onload = (e) => {
        try {
          if (e.target) {
            const errRes = JSON.parse(e.target.result as string)
            ElMessage({
              message: errRes.msg || '远程调用异常！',
              type: 'error'
            })
          }
        } catch (e) {
          ElMessage({
            message: '远程调用异常！',
            type: 'error'
          })
        }
      }
      reader.readAsText(blob)
      return Promise.reject(new Error('远程调用异常！'))
    } else {
      return response.data
    }
  } else {
    const { msg, code } = response.data
    const useStore = useUserStoreHook()
    // // 根据 code 值判断是否成功
    if (code == result_code) {
      return response.data
    } else if (code === '401') {
      ElMessage({
        message: msg,
        type: 'error'
      })
      // token 超时
      useStore.resetToken().then(() => {
        location.reload()
      })
    } else {
      ElMessage({
        message: msg,
        type: 'error'
      })
      return Promise.reject(new Error(msg))
    }
  }
}, (error: AxiosError) => {
  ElMessage({
    message: error.response.data.msg || '服务器出错',
    type: 'error'
  })
  return Promise.reject(error)
})

export default service
